package sy6_Behavioral_Pattern.command.ex2;
/*
 * 实现一次撤销（Undo）和恢复（Redo）功能
 * 加法器做为接收者
 * 撤销操作通过加法器加原来的相反数来实现
 * 恢复操作通过加法器再加原来的数实现
 */

class Adder {  //接收者
	private int num=0; 

	public int add(int value) {
		num += value;  //累加
		return num;
	}
}

abstract class AbstractCommand {  //抽象命令
	public abstract int execute(int value);  //命令执行方法
	public abstract int undo();  //撤销方法
	public abstract int redo();  //恢复方法
}

class ConcreteCommand extends AbstractCommand {  //具体命令
	private Adder adder;  //在具体命令里维持一个接收者
	private int value;
	
	public ConcreteCommand(Adder adder) {  //有参构造方法
		this.adder = adder;
	}

	@Override
    public int execute(int value) {
		this.value=value;
		return adder.add(value);
	}
	
	@Override
	public int undo() {
          return adder.add(-value);
	}
	
	@Override
	public int redo() {
          return adder.add(value);
	}
}

class Calculator {  //发送者

	private AbstractCommand command;  //Calculator聚合AbstractCommand
	
	public void setCommand(AbstractCommand command) {
		this.command = command;
	}

	public void compute(int value) {
		int i=command.execute(value);  //调用命令
		System.out.println("执行运算，运算结果为："+i);
		
	}

	public void undo() {
		int i=command.undo();  //调用命令
		System.out.println("执行撤销，运算结果为："+i);
     }
	
	public void redo(){  
		int i=command.redo();  //调用命令
		System.out.println("执行恢复，运算结果为："+i);	
	}
}

public class Client {  //客户端
	
	public static void main(String[] args) {
		Adder adder=new Adder();  //接收者；Client关联Adder
		
		Calculator calculator = new Calculator();  //调用者
		//Client依赖ConcreteCommand
	    calculator.setCommand(new ConcreteCommand(adder));
	    
	    calculator.compute(5);  //结果为5
	    calculator.compute(34); //结果为39
	    calculator.undo();      //撤销操作，结果为5
	    calculator.redo();      //恢复操作，结果为39
	}
}
